using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Admin.NET.Application.Entity.Business;
using Admin.NET.Application.Service.Report.Dto;
using Admin.NET.Application.Service.ReportForms.Dto;
using Admin.NET.Core;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using Magicodes.ExporterAndImporter.Excel;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;

namespace Admin.NET.Application.Service.ReportForms;

/// <summary>
/// 能耗分析报表
/// </summary>
[ApiDescriptionSettings(new string[] { "业务应用" }, Order = 100)]
public class EnergyService : IDynamicApiController, ITransient, IPrivateDependency
{
	private readonly SqlSugarRepository<PowerConsumptionRecord> _rep;

	private readonly SqlSugarRepository<WaterConsumptionRecord> _repwater;

	private readonly SqlSugarRepository<ElectricMeter> _meterRep;

	public EnergyService(SqlSugarRepository<PowerConsumptionRecord> rep, SqlSugarRepository<ElectricMeter> meterRep, SqlSugarRepository<WaterConsumptionRecord> repwater)
	{
		_repwater = repwater;
		_rep = rep;
		_meterRep = meterRep;
	}

	/// <summary>
	/// 获取统计报表
	/// </summary>
	/// <param name="input"></param>
	/// <returns></returns>
	[HttpGet("/energy/chartsapp")]
	public async Task<dynamic> GetChartsAPP([FromQuery] EnergyInput input)
	{
		(ISugarQueryable<PowerConsumptionRecord>, DateTime, DateTime) input2 = GetInput(input);
		ISugarQueryable<PowerConsumptionRecord> data = input2.Item1;
		DateTime begin = input2.Item2;
		DateTime end = input2.Item3;
		List<EnergyChartsOutput> result = new List<EnergyChartsOutput>();
		if (input.Type == 0)
		{
			List<int> tmpData = Enumerable.Range(input.BeginYear.Value, input.EndYear.Value + 1 - input.BeginYear.Value).ToList();
			_rep.Context.Reportable(tmpData).ToQueryable<int>();
			List<EnergyChartsOutput> info = (from u in data
				group u by SqlFunc.MappingColumn<string>("date_trunc('year', create_time)") into u
				select new EnergyChartsOutput
				{
					total = SqlFunc.AggregateSum(u.CombinedActiveTotalElectricEnergyDifference),
					sharpTotal = SqlFunc.AggregateSum(u.CombinedActiveSharpElectricEnergyDifference),
					peakTotal = SqlFunc.AggregateSum(u.CombinedActivePeakElectricEnergyDifference),
					flatTotal = SqlFunc.AggregateSum(u.CombinedActiveFlatElectricEnergyDifference),
					valleyTotal = SqlFunc.AggregateSum(u.CombinedActiveValleyElectricEnergyDifference),
					amount = SqlFunc.AggregateSum(u.Amount),
					date = SqlFunc.MappingColumn<string>("date_trunc('year', create_time)")
				}).ToList();
			foreach (int item in tmpData)
			{
				EnergyChartsOutput model = info.Where((EnergyChartsOutput u) => DateTime.Parse(u.date).Year == item).FirstOrDefault();
				if (model != null)
				{
					model.total = Math.Round(model.total, 2);
					model.sharpTotal = Math.Round(model.sharpTotal, 2);
					model.peakTotal = Math.Round(model.peakTotal, 2);
					model.flatTotal = Math.Round(model.flatTotal, 2);
					model.valleyTotal = Math.Round(model.valleyTotal, 2);
					if (model.amount.HasValue)
					{
						model.amount = Math.Round(model.amount.Value, 2);
					}
					result.Add(model);
				}
				else
				{
					result.Add(new EnergyChartsOutput
					{
						date = item + "-01-01".ToString()
					});
				}
			}
		}
		else if (input.Type == 1)
		{
			int months = (end.Year - begin.Year) * 12 + end.Month - begin.Month;
			List<DateTime> tmpData = (from s in Enumerable.Range(0, months)
				select begin.AddMonths(s)).ToList();
			List<EnergyChartsOutput> info = (from u in data
				group u by SqlFunc.MappingColumn<string>("date_trunc('month', create_time)") into u
				select new EnergyChartsOutput
				{
					total = SqlFunc.AggregateSum(u.CombinedActiveTotalElectricEnergyDifference),
					sharpTotal = SqlFunc.AggregateSum(u.CombinedActiveSharpElectricEnergyDifference),
					peakTotal = SqlFunc.AggregateSum(u.CombinedActivePeakElectricEnergyDifference),
					flatTotal = SqlFunc.AggregateSum(u.CombinedActiveFlatElectricEnergyDifference),
					valleyTotal = SqlFunc.AggregateSum(u.CombinedActiveValleyElectricEnergyDifference),
					amount = SqlFunc.AggregateSum(u.Amount),
					date = SqlFunc.MappingColumn<string>("date_trunc('month', create_time)")
				}).ToList();
			foreach (DateTime item in tmpData)
			{
				EnergyChartsOutput model = info.Where((EnergyChartsOutput u) => DateTime.Parse(u.date).ToString("yyyy-MM") == item.ToString("yyyy-MM")).FirstOrDefault();
				if (model != null)
				{
					result.Add(model);
					continue;
				}
				result.Add(new EnergyChartsOutput
				{
					date = item.ToString("yyyy-MM-01")
				});
			}
		}
		else if (input.Type == 2)
		{
			double months = (end - begin).TotalDays;
			List<DateTime> tmpData = (from s in Enumerable.Range(0, (int)months)
				select begin.AddDays(s)).ToList();
			List<EnergyChartsOutput> info = (from u in data
				group u by SqlFunc.MappingColumn<string>("date_trunc('day', create_time)") into u
				select new EnergyChartsOutput
				{
					total = SqlFunc.AggregateSum(u.CombinedActiveTotalElectricEnergyDifference),
					sharpTotal = SqlFunc.AggregateSum(u.CombinedActiveSharpElectricEnergyDifference),
					peakTotal = SqlFunc.AggregateSum(u.CombinedActivePeakElectricEnergyDifference),
					flatTotal = SqlFunc.AggregateSum(u.CombinedActiveFlatElectricEnergyDifference),
					valleyTotal = SqlFunc.AggregateSum(u.CombinedActiveValleyElectricEnergyDifference),
					amount = SqlFunc.AggregateSum(u.Amount),
					date = SqlFunc.MappingColumn<string>("date_trunc('day', create_time)")
				}).ToList();
			foreach (DateTime item in tmpData)
			{
				EnergyChartsOutput model = info.Where((EnergyChartsOutput u) => DateTime.Parse(u.date).ToString("yyyy-MM-dd") == item.ToString("yyyy-MM-dd")).FirstOrDefault();
				if (model != null)
				{
					result.Add(model);
					continue;
				}
				result.Add(new EnergyChartsOutput
				{
					date = item.ToString("yyyy-MM-dd")
				});
			}
		}
		List<EnergyChartsOutput> sortResult = result.OrderBy((EnergyChartsOutput o) => o.date).ToList();
		return new
		{
			date = sortResult.Select(delegate(EnergyChartsOutput s)
			{
				if (input.Type == 0)
				{
					return DateTime.Parse(s.date).Year + "年";
				}
				return (input.Type == 1) ? (DateTime.Parse(s.date).Month + "月") : (DateTime.Parse(s.date).Date.ToString("yyyy-MM-dd") + "日");
			}).ToList(),
			total = sortResult.Select((EnergyChartsOutput s) => new
			{
				value = s.total
			}).ToList(),
			sharpTotal = sortResult.Select((EnergyChartsOutput s) => new
			{
				value = s.sharpTotal
			}).ToList(),
			peakTotal = sortResult.Select((EnergyChartsOutput s) => new
			{
				value = s.peakTotal
			}).ToList(),
			flatTotal = sortResult.Select((EnergyChartsOutput s) => new
			{
				value = s.flatTotal
			}).ToList(),
			valleyTotal = sortResult.Select((EnergyChartsOutput s) => new
			{
				value = s.valleyTotal
			}).ToList(),
			amount = sortResult.Select((EnergyChartsOutput s) => new
			{
				value = s.amount
			}).ToList()
		};
	}

	/// <summary>
	/// 获取统计报表
	/// </summary>
	/// <param name="input"></param>
	/// <returns></returns>
	[HttpGet("/energy/chartsappwater")]
	public async Task<dynamic> GetChartsAPPWater([FromQuery] EnergyInput input)
	{
		(ISugarQueryable<WaterConsumptionRecord>, DateTime, DateTime) waterInput = GetWaterInput(input);
		ISugarQueryable<WaterConsumptionRecord> data = waterInput.Item1;
		DateTime begin = waterInput.Item2;
		DateTime end = waterInput.Item3;
		List<EnergyChartsOutput> result = new List<EnergyChartsOutput>();
		if (input.Type == 0)
		{
			List<int> tmpData = Enumerable.Range(input.BeginYear.Value, input.EndYear.Value + 1 - input.BeginYear.Value).ToList();
			_rep.Context.Reportable(tmpData).ToQueryable<int>();
			List<EnergyChartsOutput> info = (from u in data
				group u by SqlFunc.MappingColumn<string>("date_trunc('year', create_time)") into u
				select new EnergyChartsOutput
				{
					total = SqlFunc.AggregateSum(u.TotalUsageDifference),
					amount = SqlFunc.AggregateSum(u.Amount),
					date = SqlFunc.MappingColumn<string>("date_trunc('year', create_time)")
				}).ToList();
			foreach (int item in tmpData)
			{
				EnergyChartsOutput model = info.Where((EnergyChartsOutput u) => DateTime.Parse(u.date).Year == item).FirstOrDefault();
				if (model != null)
				{
					model.total = Math.Round(model.total, 2);
					if (model.amount.HasValue)
					{
						model.amount = Math.Round(model.amount.Value, 2);
					}
					result.Add(model);
				}
				else
				{
					result.Add(new EnergyChartsOutput
					{
						date = item + "-01-01".ToString()
					});
				}
			}
		}
		else if (input.Type == 1)
		{
			int months = (end.Year - begin.Year) * 12 + end.Month - begin.Month;
			List<DateTime> tmpData = (from s in Enumerable.Range(0, months)
				select begin.AddMonths(s)).ToList();
			List<EnergyChartsOutput> info = (from u in data
				group u by SqlFunc.MappingColumn<string>("date_trunc('month', create_time)") into u
				select new EnergyChartsOutput
				{
					total = SqlFunc.AggregateSum(u.TotalUsageDifference),
					amount = SqlFunc.AggregateSum(u.Amount),
					date = SqlFunc.MappingColumn<string>("date_trunc('month', create_time)")
				}).ToList();
			foreach (DateTime item in tmpData)
			{
				EnergyChartsOutput model = info.Where((EnergyChartsOutput u) => DateTime.Parse(u.date).ToString("yyyy-MM") == item.ToString("yyyy-MM")).FirstOrDefault();
				if (model != null)
				{
					result.Add(model);
					continue;
				}
				result.Add(new EnergyChartsOutput
				{
					date = item.ToString("yyyy-MM-01")
				});
			}
		}
		else if (input.Type == 2)
		{
			double months = (end - begin).TotalDays;
			List<DateTime> tmpData = (from s in Enumerable.Range(0, (int)months)
				select begin.AddDays(s)).ToList();
			List<EnergyChartsOutput> info = (from u in data
				group u by SqlFunc.MappingColumn<string>("date_trunc('day', create_time)") into u
				select new EnergyChartsOutput
				{
					total = SqlFunc.AggregateSum(u.TotalUsageDifference),
					amount = SqlFunc.AggregateSum(u.Amount),
					date = SqlFunc.MappingColumn<string>("date_trunc('day', create_time)")
				}).ToList();
			foreach (DateTime item in tmpData)
			{
				EnergyChartsOutput model = info.Where((EnergyChartsOutput u) => DateTime.Parse(u.date).ToString("yyyy-MM-dd") == item.ToString("yyyy-MM-dd")).FirstOrDefault();
				if (model != null)
				{
					result.Add(model);
					continue;
				}
				result.Add(new EnergyChartsOutput
				{
					date = item.ToString("yyyy-MM-dd")
				});
			}
		}
		List<EnergyChartsOutput> sortResult = result.OrderBy((EnergyChartsOutput o) => o.date).ToList();
		return new
		{
			date = sortResult.Select(delegate(EnergyChartsOutput s)
			{
				if (input.Type == 0)
				{
					return DateTime.Parse(s.date).Year + "年";
				}
				return (input.Type == 1) ? (DateTime.Parse(s.date).Month + "月") : (DateTime.Parse(s.date).Date.ToString("yyyy-MM-dd") + "日");
			}).ToList(),
			total = sortResult.Select((EnergyChartsOutput s) => new
			{
				value = s.total
			}).ToList(),
			sharpTotal = sortResult.Select((EnergyChartsOutput s) => new
			{
				value = s.sharpTotal
			}).ToList(),
			peakTotal = sortResult.Select((EnergyChartsOutput s) => new
			{
				value = s.peakTotal
			}).ToList(),
			flatTotal = sortResult.Select((EnergyChartsOutput s) => new
			{
				value = s.flatTotal
			}).ToList(),
			valleyTotal = sortResult.Select((EnergyChartsOutput s) => new
			{
				value = s.valleyTotal
			}).ToList(),
			amount = sortResult.Select((EnergyChartsOutput s) => new
			{
				value = s.amount
			}).ToList()
		};
	}

	private (ISugarQueryable<WaterConsumptionRecord>, DateTime, DateTime) GetWaterInput(EnergyInput input)
	{
		ISugarQueryable<WaterConsumptionRecord> data = _repwater.AsQueryable().WhereIF(input.BuildingId.HasValue, (WaterConsumptionRecord u) => (long?)u.BuildingId == input.BuildingId).WhereIF(input.RoomId.HasValue, (WaterConsumptionRecord u) => (long?)u.RoomId == input.RoomId)
			.WhereIF(!string.IsNullOrWhiteSpace(input.Sn), (WaterConsumptionRecord u) => u.Sn == input.Sn);
		DateTime begin = DateTime.MinValue;
		DateTime end = DateTime.MinValue;
		switch (input.Type)
		{
		case 0:
			if (!input.BeginYear.HasValue || !input.EndYear.HasValue)
			{
				throw Oops.Bah("请选择日期范围");
			}
			begin = DateTime.Parse(input.BeginYear + "-01-01");
			end = DateTime.Parse(input.EndYear + 1 + "-01-01");
			break;
		case 1:
			if (!input.BeginYear.HasValue || !input.EndYear.HasValue || !input.BeginMonth.HasValue || !input.EndMonth.HasValue)
			{
				throw Oops.Bah("请选择日期范围");
			}
			begin = DateTime.Parse(input.BeginYear + "-" + input.BeginMonth + "-01");
			if (input.EndMonth > 11)
			{
				end = DateTime.Parse(input.EndYear + 1 + "-01-01");
			}
			else
			{
				end = DateTime.Parse(input.EndYear + "-" + (input.EndMonth + 1) + "-01");
			}
			break;
		case 2:
			if (!input.BeginYear.HasValue || !input.EndYear.HasValue || !input.BeginMonth.HasValue || !input.EndMonth.HasValue || !input.BeginDay.HasValue || !input.EndDay.HasValue)
			{
				throw Oops.Bah("请选择日期范围");
			}
			begin = DateTime.Parse(input.BeginYear + "-" + input.BeginMonth + "-" + input.BeginDay);
			if (input.EndMonth > 11)
			{
				end = DateTime.Parse(input.EndYear + 1 + "-01-01");
				break;
			}
			end = DateTime.Parse(input.EndYear + "-" + input.EndMonth + "-" + input.EndDay).AddDays(1.0);
			break;
		default:
			throw Oops.Bah("请选择日期类型");
		}
		data = data.Where((WaterConsumptionRecord u) => u.CreateTime >= begin && u.CreateTime < end);
		return (data, begin, end);
	}

	/// <summary>
	/// 获取统计报表
	/// </summary>
	/// <param name="input"></param>
	/// <returns></returns>
	[HttpGet("/energy/charts")]
	public async Task<dynamic> GetCharts([FromQuery] EnergyInput input)
	{
		(ISugarQueryable<PowerConsumptionRecord>, DateTime, DateTime) input2 = GetInput(input);
		ISugarQueryable<PowerConsumptionRecord> data = input2.Item1;
		DateTime begin = input2.Item2;
		DateTime end = input2.Item3;
		List<EnergyChartsOutput> result = new List<EnergyChartsOutput>();
		if (input.Type == 0)
		{
			List<int> tmpData = Enumerable.Range(input.BeginYear.Value, input.EndYear.Value + 1 - input.BeginYear.Value).ToList();
			_rep.Context.Reportable(tmpData).ToQueryable<int>();
			List<EnergyChartsOutput> info = (from u in data
				group u by SqlFunc.MappingColumn<string>("date_trunc('year', create_time)") into u
				select new EnergyChartsOutput
				{
					total = SqlFunc.AggregateSum(u.CombinedActiveTotalElectricEnergyDifference),
					sharpTotal = SqlFunc.AggregateSum(u.CombinedActiveSharpElectricEnergyDifference),
					peakTotal = SqlFunc.AggregateSum(u.CombinedActivePeakElectricEnergyDifference),
					flatTotal = SqlFunc.AggregateSum(u.CombinedActiveFlatElectricEnergyDifference),
					valleyTotal = SqlFunc.AggregateSum(u.CombinedActiveValleyElectricEnergyDifference),
					deepvalleyTotal = SqlFunc.AggregateSum(u.CombinedActiveDeepValleyElectricEnergyDifference ?? 0m),
					amount = SqlFunc.AggregateSum(u.Amount),
					date = SqlFunc.MappingColumn<string>("date_trunc('year', create_time)")
				}).ToList();
			foreach (int item in tmpData)
			{
				EnergyChartsOutput model = info.Where((EnergyChartsOutput u) => DateTime.Parse(u.date).Year == item).FirstOrDefault();
				if (model != null)
				{
					model.total = Math.Round(model.total, 2);
					model.sharpTotal = Math.Round(model.sharpTotal, 2);
					model.peakTotal = Math.Round(model.peakTotal, 2);
					model.flatTotal = Math.Round(model.flatTotal, 2);
					model.valleyTotal = Math.Round(model.valleyTotal, 2);
					model.deepvalleyTotal = Math.Round(model.deepvalleyTotal, 2);
					if (model.amount.HasValue)
					{
						model.amount = Math.Round(model.amount.Value, 2);
					}
					result.Add(model);
				}
				else
				{
					result.Add(new EnergyChartsOutput
					{
						date = item + "-01-01 00:00:00".ToString()
					});
				}
			}
		}
		else if (input.Type == 1)
		{
			int months = (end.Year - begin.Year) * 12 + end.Month - begin.Month;
			List<DateTime> tmpData = (from s in Enumerable.Range(0, months)
				select begin.AddMonths(s)).ToList();
			List<EnergyChartsOutput> info = (from u in data
				group u by SqlFunc.MappingColumn<string>("date_trunc('month', create_time)") into u
				select new EnergyChartsOutput
				{
					total = SqlFunc.AggregateSum(u.CombinedActiveTotalElectricEnergyDifference),
					sharpTotal = SqlFunc.AggregateSum(u.CombinedActiveSharpElectricEnergyDifference),
					peakTotal = SqlFunc.AggregateSum(u.CombinedActivePeakElectricEnergyDifference),
					flatTotal = SqlFunc.AggregateSum(u.CombinedActiveFlatElectricEnergyDifference),
					valleyTotal = SqlFunc.AggregateSum(u.CombinedActiveValleyElectricEnergyDifference),
					deepvalleyTotal = SqlFunc.AggregateSum(u.CombinedActiveDeepValleyElectricEnergyDifference ?? 0m),
					amount = SqlFunc.AggregateSum(u.Amount),
					date = SqlFunc.MappingColumn<string>("date_trunc('month', create_time)")
				}).ToList();
			foreach (DateTime item in tmpData)
			{
				EnergyChartsOutput model = info.Where((EnergyChartsOutput u) => DateTime.Parse(u.date).ToString("yyyy-MM") == item.ToString("yyyy-MM")).FirstOrDefault();
				if (model != null)
				{
					result.Add(model);
					continue;
				}
				result.Add(new EnergyChartsOutput
				{
					date = item.ToString("yyyy-MM-01 00:00:00")
				});
			}
		}
		else if (input.Type == 2)
		{
			double months = (end - begin).TotalDays;
			List<DateTime> tmpData = (from s in Enumerable.Range(0, (int)months)
				select begin.AddDays(s)).ToList();
			List<EnergyChartsOutput> info = (from u in data
				group u by SqlFunc.MappingColumn<string>("date_trunc('day', create_time)") into u
				select new EnergyChartsOutput
				{
					total = SqlFunc.AggregateSum(u.CombinedActiveTotalElectricEnergyDifference),
					sharpTotal = SqlFunc.AggregateSum(u.CombinedActiveSharpElectricEnergyDifference),
					peakTotal = SqlFunc.AggregateSum(u.CombinedActivePeakElectricEnergyDifference),
					flatTotal = SqlFunc.AggregateSum(u.CombinedActiveFlatElectricEnergyDifference),
					valleyTotal = SqlFunc.AggregateSum(u.CombinedActiveValleyElectricEnergyDifference),
					deepvalleyTotal = SqlFunc.AggregateSum(u.CombinedActiveDeepValleyElectricEnergyDifference ?? 0m),
					amount = SqlFunc.AggregateSum(u.Amount),
					date = SqlFunc.MappingColumn<string>("date_trunc('day', create_time)")
				}).ToList();
			foreach (DateTime item in tmpData)
			{
				EnergyChartsOutput model = info.Where((EnergyChartsOutput u) => DateTime.Parse(u.date).ToString("yyyy-MM-dd") == item.ToString("yyyy-MM-dd")).FirstOrDefault();
				if (model != null)
				{
					result.Add(model);
					continue;
				}
				result.Add(new EnergyChartsOutput
				{
					date = item.ToString("yyyy-MM-dd 00:00:00")
				});
			}
		}
		List<EnergyChartsOutput> sortResult = result.OrderBy((EnergyChartsOutput o) => DateTime.Parse(o.date)).ToList();
		return new
		{
			date = sortResult.Select(delegate(EnergyChartsOutput s)
			{
				if (input.Type == 0)
				{
					return DateTime.Parse(s.date).Year + "年";
				}
				return (input.Type == 1) ? (DateTime.Parse(s.date).Month + "月") : DateTime.Parse(s.date).Date.ToString("yyyy-MM-dd");
			}).ToList(),
			total = sortResult.Select((EnergyChartsOutput s) => new
			{
				value = s.total
			}).ToList(),
			sharpTotal = sortResult.Select((EnergyChartsOutput s) => new
			{
				value = s.sharpTotal
			}).ToList(),
			peakTotal = sortResult.Select((EnergyChartsOutput s) => new
			{
				value = s.peakTotal
			}).ToList(),
			flatTotal = sortResult.Select((EnergyChartsOutput s) => new
			{
				value = s.flatTotal
			}).ToList(),
			valleyTotal = sortResult.Select((EnergyChartsOutput s) => new
			{
				value = s.valleyTotal
			}).ToList(),
			deepvalleyTotal = sortResult.Select((EnergyChartsOutput s) => new
			{
				value = s.deepvalleyTotal
			}).ToList(),
			amount = sortResult.Select((EnergyChartsOutput s) => new
			{
				value = s.amount
			}).ToList()
		};
	}

	private (ISugarQueryable<PowerConsumptionRecord>, DateTime, DateTime) GetInput(EnergyInput input)
	{
		ISugarQueryable<PowerConsumptionRecord> data = _rep.AsQueryable().WhereIF(input.BuildingId.HasValue, (PowerConsumptionRecord u) => u.BuildingId == input.BuildingId).WhereIF(input.RoomId.HasValue, (PowerConsumptionRecord u) => u.RoomId == input.RoomId)
			.WhereIF(!string.IsNullOrWhiteSpace(input.Sn), (PowerConsumptionRecord u) => u.Sn == input.Sn);
		DateTime begin = DateTime.MinValue;
		DateTime end = DateTime.MinValue;
		switch (input.Type)
		{
		case 0:
			if (!input.BeginYear.HasValue || !input.EndYear.HasValue)
			{
				throw Oops.Bah("请选择日期范围");
			}
			begin = DateTime.Parse(input.BeginYear + "-01-01");
			end = DateTime.Parse(input.EndYear + 1 + "-01-01");
			break;
		case 1:
			if (!input.BeginYear.HasValue || !input.EndYear.HasValue || !input.BeginMonth.HasValue || !input.EndMonth.HasValue)
			{
				throw Oops.Bah("请选择日期范围");
			}
			begin = DateTime.Parse(input.BeginYear + "-" + input.BeginMonth + "-01");
			if (input.EndMonth > 11)
			{
				end = DateTime.Parse(input.EndYear + 1 + "-01-01");
			}
			else
			{
				end = DateTime.Parse(input.EndYear + "-" + (input.EndMonth + 1) + "-01");
			}
			break;
		case 2:
			if (!input.BeginYear.HasValue || !input.EndYear.HasValue || !input.BeginMonth.HasValue || !input.EndMonth.HasValue || !input.BeginDay.HasValue || !input.EndDay.HasValue)
			{
				throw Oops.Bah("请选择日期范围");
			}
			begin = DateTime.Parse(input.BeginYear + "-" + input.BeginMonth + "-" + input.BeginDay);
			if (input.EndMonth > 11)
			{
				end = DateTime.Parse(input.EndYear + 1 + "-01-01");
				break;
			}
			end = DateTime.Parse(input.EndYear + "-" + input.EndMonth + "-" + input.EndDay).AddDays(1.0);
			break;
		default:
			throw Oops.Bah("请选择日期类型");
		}
		data = data.Where((PowerConsumptionRecord u) => u.CreateTime >= begin && u.CreateTime < end);
		return (data, begin, end);
	}

	/// <summary>
	/// 按照表sn查询能耗统计
	/// </summary>
	/// <param name="input"></param>
	/// <returns></returns>
	[HttpGet("/energy/meters")]
	public async Task<dynamic> GetMeterList([FromQuery] EnergyInput input)
	{
		ISugarQueryable<ExportMeterEnergyDto> data = GetMeterQueryable(input);
		SqlSugarPagedList<ExportMeterEnergyDto> result = await data.OrderBy((ExportMeterEnergyDto u) => u.sn).OrderBy((ExportMeterEnergyDto u) => u.date, OrderByType.Desc).ToPagedListAsync(input.Page, input.PageSize);
		string format = "yyyy";
		if (input.Type == 0)
		{
		}
		if (input.Type == 1)
		{
			format = "yyyy-MM";
		}
		List<ElectricMeterFreeze> list = new List<ElectricMeterFreeze>();
		if (input.Type == 2)
		{
			string[] snarr = result.Items.Select((ExportMeterEnergyDto u) => u.sn).Distinct().ToArray();
			DateTime begin = DateTime.Parse(input.BeginYear + "-" + input.BeginMonth + "-" + input.BeginDay);
			DateTime end = DateTime.Parse(input.EndYear + "-" + input.EndMonth + "-" + input.EndDay);
			list = await (from u in _meterRep.Context.Queryable<ElectricMeterFreeze>()
				where u.ElectricMeterFreezeTime >= begin && u.ElectricMeterFreezeTime <= end && snarr.Contains(u.Sn)
				select u).ToListAsync();
			format = "yyyy-MM-dd";
		}
		foreach (ExportMeterEnergyDto item in result.Items)
		{
			item.date = DateTime.Parse(item.date).ToString(format);
			if (input.Type == 2)
			{
				item.FreezeCombinedActiveTotalElectricEnergy = list.Where((ElectricMeterFreeze u) => u.Sn == item.sn && u.ElectricMeterFreezeTime.ToString(format) == item.date).FirstOrDefault()?.CombinedActiveTotalElectricEnergy;
				item.FreezeCombinedActiveFlatElectricEnergy = list.Where((ElectricMeterFreeze u) => u.Sn == item.sn && u.ElectricMeterFreezeTime.ToString(format) == item.date).FirstOrDefault()?.CombinedActiveFlatElectricEnergy;
				item.FreezeCombinedActivePeakElectricEnergy = list.Where((ElectricMeterFreeze u) => u.Sn == item.sn && u.ElectricMeterFreezeTime.ToString(format) == item.date).FirstOrDefault()?.CombinedActivePeakElectricEnergy;
				item.FreezeCombinedActiveSharpElectricEnergy = list.Where((ElectricMeterFreeze u) => u.Sn == item.sn && u.ElectricMeterFreezeTime.ToString(format) == item.date).FirstOrDefault()?.CombinedActiveSharpElectricEnergy;
				item.FreezeCombinedActiveValleyElectricEnergy = list.Where((ElectricMeterFreeze u) => u.Sn == item.sn && u.ElectricMeterFreezeTime.ToString(format) == item.date).FirstOrDefault()?.CombinedActiveValleyElectricEnergy;
				item.FreezeCombinedActiveDeepValleyElectricEnergy = list.Where((ElectricMeterFreeze u) => u.Sn == item.sn && u.ElectricMeterFreezeTime.ToString(format) == item.date).FirstOrDefault()?.CombinedActiveDeepValleyElectricEnergy;
			}
		}
		return result;
	}

	/// <summary>
	/// 获取统计报表
	/// </summary>
	/// <param name="input"></param>
	/// <returns></returns>
	[HttpGet("/energy/chartswater")]
	public async Task<dynamic> GetChartsWater([FromQuery] EnergyInput input)
	{
		(ISugarQueryable<WaterConsumptionRecord>, DateTime, DateTime) water2Input = GetWater2Input(input);
		ISugarQueryable<WaterConsumptionRecord> data = water2Input.Item1;
		DateTime begin = water2Input.Item2;
		DateTime end = water2Input.Item3;
		List<EnergyChartsOutput> result = new List<EnergyChartsOutput>();
		if (input.Type == 0)
		{
			List<int> tmpData = Enumerable.Range(input.BeginYear.Value, input.EndYear.Value + 1 - input.BeginYear.Value).ToList();
			_rep.Context.Reportable(tmpData).ToQueryable<int>();
			List<EnergyChartsOutput> info = (from u in data
				group u by SqlFunc.MappingColumn<string>("date_trunc('year', create_time)") into u
				select new EnergyChartsOutput
				{
					total = SqlFunc.AggregateSum(u.TotalUsageDifference),
					amount = SqlFunc.AggregateSum(u.Amount),
					date = SqlFunc.MappingColumn<string>("date_trunc('year', create_time)")
				}).ToList();
			foreach (int item in tmpData)
			{
				EnergyChartsOutput model = info.Where((EnergyChartsOutput u) => DateTime.Parse(u.date).Year == item).FirstOrDefault();
				if (model != null)
				{
					model.total = Math.Round(model.total, 2);
					if (model.amount.HasValue)
					{
						model.amount = Math.Round(model.amount.Value, 2);
					}
					result.Add(model);
				}
				else
				{
					result.Add(new EnergyChartsOutput
					{
						date = item + "-01-01 00:00:00".ToString()
					});
				}
			}
		}
		else if (input.Type == 1)
		{
			int months = (end.Year - begin.Year) * 12 + end.Month - begin.Month;
			List<DateTime> tmpData = (from s in Enumerable.Range(0, months)
				select begin.AddMonths(s)).ToList();
			List<EnergyChartsOutput> info = (from u in data
				group u by SqlFunc.MappingColumn<string>("date_trunc('month', create_time)") into u
				select new EnergyChartsOutput
				{
					total = SqlFunc.AggregateSum(u.TotalUsageDifference),
					amount = SqlFunc.AggregateSum(u.Amount),
					date = SqlFunc.MappingColumn<string>("date_trunc('month', create_time)")
				}).ToList();
			foreach (DateTime item in tmpData)
			{
				EnergyChartsOutput model = info.Where((EnergyChartsOutput u) => DateTime.Parse(u.date).ToString("yyyy-MM") == item.ToString("yyyy-MM")).FirstOrDefault();
				if (model != null)
				{
					result.Add(model);
					continue;
				}
				result.Add(new EnergyChartsOutput
				{
					date = item.ToString("yyyy-MM-01 00:00:00")
				});
			}
		}
		else if (input.Type == 2)
		{
			double months = (end - begin).TotalDays;
			List<DateTime> tmpData = (from s in Enumerable.Range(0, (int)months)
				select begin.AddDays(s)).ToList();
			List<EnergyChartsOutput> info = (from u in data
				group u by SqlFunc.MappingColumn<string>("date_trunc('day', create_time)") into u
				select new EnergyChartsOutput
				{
					total = SqlFunc.AggregateSum(u.TotalUsageDifference),
					amount = SqlFunc.AggregateSum(u.Amount),
					date = SqlFunc.MappingColumn<string>("date_trunc('day', create_time)")
				}).ToList();
			foreach (DateTime item in tmpData)
			{
				EnergyChartsOutput model = info.Where((EnergyChartsOutput u) => DateTime.Parse(u.date).ToString("yyyy-MM-dd") == item.ToString("yyyy-MM-dd")).FirstOrDefault();
				if (model != null)
				{
					result.Add(model);
					continue;
				}
				result.Add(new EnergyChartsOutput
				{
					date = item.ToString("yyyy-MM-dd 00:00:00")
				});
			}
		}
		List<EnergyChartsOutput> sortResult = result.OrderBy((EnergyChartsOutput o) => DateTime.Parse(o.date)).ToList();
		return new
		{
			date = sortResult.Select(delegate(EnergyChartsOutput s)
			{
				if (input.Type == 0)
				{
					return DateTime.Parse(s.date).Year + "年";
				}
				return (input.Type == 1) ? (DateTime.Parse(s.date).Month + "月") : DateTime.Parse(s.date).Date.ToString("yyyy-MM-dd");
			}).ToList(),
			total = sortResult.Select((EnergyChartsOutput s) => new
			{
				value = s.total
			}).ToList(),
			amount = sortResult.Select((EnergyChartsOutput s) => new
			{
				value = s.amount
			}).ToList()
		};
	}

	/// <summary>
	/// 获取抄表结算详细记录
	/// </summary>
	/// <param name="input"></param>
	/// <returns></returns>
	[HttpGet("/energy/recordswater")]
	public async Task<dynamic> GetMeterRecordWater([FromQuery] EnergyInput input)
	{
		(ISugarQueryable<WaterConsumptionRecord>, DateTime, DateTime) water2Input = GetWater2Input(input);
		var (data, _, _) = water2Input;
		_ = water2Input.Item2;
		_ = water2Input.Item3;
		return await data.OrderByDescending((WaterConsumptionRecord o) => o.CreateTime).ToPagedListAsync(input.Page, input.PageSize);
	}

	/// <summary>
	/// 按照表sn查询能耗统计
	/// </summary>
	/// <param name="input"></param>
	/// <returns></returns>
	[HttpGet("/energy/meterswater")]
	public async Task<dynamic> GetMeterWaterList([FromQuery] EnergyInput input)
	{
		ISugarQueryable<ExportMeterEnergyDto> data = GetMeterWaterQueryable(input);
		SqlSugarPagedList<ExportMeterEnergyDto> result = await data.OrderBy((ExportMeterEnergyDto u) => u.sn).OrderBy((ExportMeterEnergyDto u) => u.date, OrderByType.Desc).ToPagedListAsync(input.Page, input.PageSize);
		string format = "yyyy";
		if (input.Type == 0)
		{
		}
		if (input.Type == 1)
		{
			format = "yyyy-MM";
		}
		if (input.Type == 2)
		{
			format = "yyyy-MM-dd";
		}
		foreach (ExportMeterEnergyDto item in result.Items)
		{
			item.date = DateTime.Parse(item.date).ToString(format);
		}
		return result;
	}

	private ISugarQueryable<ExportMeterEnergyDto> GetMeterWaterQueryable(EnergyInput input)
	{
		(ISugarQueryable<WaterConsumptionRecord>, DateTime, DateTime) water2Input = GetWater2Input(input);
		ISugarQueryable<WaterConsumptionRecord> data = water2Input.Item1;
		DateTime begin = water2Input.Item2;
		DateTime end = water2Input.Item3;
		string format = "year";
		if (input.Type == 0)
		{
		}
		if (input.Type == 1)
		{
			format = "month";
		}
		if (input.Type == 2)
		{
			format = "day";
		}
		ISugarQueryable<WaterConsumptionRecord> queryableRight = data;
		return from u in queryableRight
			group u by SqlFunc.MappingColumn<string>($"date_trunc('{format}', create_time),sn") into u
			select new ExportMeterEnergyDto
			{
				total = SqlFunc.AggregateSum(u.TotalUsageDifference),
				sn = u.Sn,
				name = SqlFunc.AggregateMin(u.Name),
				amount = SqlFunc.AggregateSum(u.Amount),
				date = SqlFunc.MappingColumn<string>($"date_trunc('{format}', create_time)")
			};
	}

	private (ISugarQueryable<WaterConsumptionRecord>, DateTime, DateTime) GetWater2Input(EnergyInput input)
	{
		ISugarQueryable<WaterConsumptionRecord> data = _repwater.AsQueryable().WhereIF(input.BuildingId.HasValue, (WaterConsumptionRecord u) => (long?)u.BuildingId == input.BuildingId).WhereIF(input.RoomId.HasValue, (WaterConsumptionRecord u) => (long?)u.RoomId == input.RoomId)
			.WhereIF(!string.IsNullOrWhiteSpace(input.Sn), (WaterConsumptionRecord u) => u.Sn == input.Sn);
		DateTime begin = DateTime.MinValue;
		DateTime end = DateTime.MinValue;
		switch (input.Type)
		{
		case 0:
			if (!input.BeginYear.HasValue || !input.EndYear.HasValue)
			{
				throw Oops.Bah("请选择日期范围");
			}
			begin = DateTime.Parse(input.BeginYear + "-01-01");
			end = DateTime.Parse(input.EndYear + 1 + "-01-01");
			break;
		case 1:
			if (!input.BeginYear.HasValue || !input.EndYear.HasValue || !input.BeginMonth.HasValue || !input.EndMonth.HasValue)
			{
				throw Oops.Bah("请选择日期范围");
			}
			begin = DateTime.Parse(input.BeginYear + "-" + input.BeginMonth + "-01");
			if (input.EndMonth > 11)
			{
				end = DateTime.Parse(input.EndYear + 1 + "-01-01");
			}
			else
			{
				end = DateTime.Parse(input.EndYear + "-" + (input.EndMonth + 1) + "-01");
			}
			break;
		case 2:
			if (!input.BeginYear.HasValue || !input.EndYear.HasValue || !input.BeginMonth.HasValue || !input.EndMonth.HasValue || !input.BeginDay.HasValue || !input.EndDay.HasValue)
			{
				throw Oops.Bah("请选择日期范围");
			}
			begin = DateTime.Parse(input.BeginYear + "-" + input.BeginMonth + "-" + input.BeginDay);
			if (input.EndMonth > 11)
			{
				end = DateTime.Parse(input.EndYear + 1 + "-01-01");
				break;
			}
			end = DateTime.Parse(input.EndYear + "-" + input.EndMonth + "-" + input.EndDay).AddDays(1.0);
			break;
		default:
			throw Oops.Bah("请选择日期类型");
		}
		data = data.Where((WaterConsumptionRecord u) => u.CreateTime >= begin && u.CreateTime < end);
		return (data, begin, end);
	}

	private ISugarQueryable<ExportMeterEnergyDto> GetMeterQueryable(EnergyInput input)
	{
		(ISugarQueryable<PowerConsumptionRecord>, DateTime, DateTime) input2 = GetInput(input);
		ISugarQueryable<PowerConsumptionRecord> data = input2.Item1;
		DateTime begin = input2.Item2;
		DateTime end = input2.Item3;
		string format = "year";
		if (input.Type == 0)
		{
		}
		if (input.Type == 1)
		{
			format = "month";
		}
		if (input.Type == 2)
		{
			format = "day";
		}
		ISugarQueryable<PowerConsumptionRecord> queryableRight = data;
		return from u in queryableRight
			group u by SqlFunc.MappingColumn<string>($"date_trunc('{format}', create_time),sn") into u
			select new ExportMeterEnergyDto
			{
				total = SqlFunc.AggregateSum(u.CombinedActiveTotalElectricEnergyDifference),
				sharpTotal = SqlFunc.AggregateSum(u.CombinedActiveSharpElectricEnergyDifference),
				peakTotal = SqlFunc.AggregateSum(u.CombinedActivePeakElectricEnergyDifference),
				flatTotal = SqlFunc.AggregateSum(u.CombinedActiveFlatElectricEnergyDifference),
				valleyTotal = SqlFunc.AggregateSum(u.CombinedActiveValleyElectricEnergyDifference),
				deepvalleyTotal = SqlFunc.AggregateSum(u.CombinedActiveDeepValleyElectricEnergyDifference ?? 0m),
				sn = u.Sn,
				name = SqlFunc.AggregateMin(u.Name),
				amount = SqlFunc.AggregateSum(u.Amount),
				date = SqlFunc.MappingColumn<string>($"date_trunc('{format}', create_time)")
			};
	}

	private ISugarQueryable<ExportMeterWaterEnergyDto> GetWaterMeterQueryable(EnergyInput input)
	{
		(ISugarQueryable<WaterConsumptionRecord>, DateTime, DateTime) water2Input = GetWater2Input(input);
		ISugarQueryable<WaterConsumptionRecord> data = water2Input.Item1;
		DateTime begin = water2Input.Item2;
		DateTime end = water2Input.Item3;
		string format = "year";
		if (input.Type == 0)
		{
		}
		if (input.Type == 1)
		{
			format = "month";
		}
		if (input.Type == 2)
		{
			format = "day";
		}
		ISugarQueryable<WaterConsumptionRecord> queryableRight = data;
		return from u in queryableRight
			group u by SqlFunc.MappingColumn<string>($"date_trunc('{format}', create_time),sn") into u
			select new ExportMeterWaterEnergyDto
			{
				total = SqlFunc.AggregateSum(u.TotalUsageDifference),
				sn = u.Sn,
				name = SqlFunc.AggregateMin(u.Name),
				amount = SqlFunc.AggregateSum(u.Amount),
				date = SqlFunc.MappingColumn<string>($"date_trunc('{format}', create_time)")
			};
	}

	/// <summary>
	/// 获取抄表结算详细记录
	/// </summary>
	/// <param name="input"></param>
	/// <returns></returns>
	[HttpGet("/energy/records")]
	public async Task<dynamic> GetMeterRecord([FromQuery] EnergyInput input)
	{
		(ISugarQueryable<PowerConsumptionRecord>, DateTime, DateTime) input2 = GetInput(input);
		var (data, _, _) = input2;
		_ = input2.Item2;
		_ = input2.Item3;
		return await data.OrderByDescending((PowerConsumptionRecord o) => o.CreateTime).ToPagedListAsync(input.Page, input.PageSize);
	}

	/// <summary>
	/// 导出电表用电量
	/// </summary>
	/// <returns></returns>
	[HttpPost("/energy/exportmeter")]
	[NonUnify]
	public async Task<IActionResult> ExporMeter([FromBody] EnergyInput input)
	{
		ISugarQueryable<ExportMeterEnergyDto> data = GetMeterQueryable(input);
		List<ExportMeterEnergyDto> meterList = await data.OrderBy((ExportMeterEnergyDto u) => u.sn).ToListAsync();
		string format = "yyyy";
		if (input.Type == 0)
		{
		}
		if (input.Type == 1)
		{
			format = "yyyy-MM";
		}
		List<ElectricMeterFreeze> list = new List<ElectricMeterFreeze>();
		if (input.Type == 2)
		{
			string[] snarr = meterList.Select((ExportMeterEnergyDto u) => u.sn).Distinct().ToArray();
			DateTime begin = DateTime.Parse(input.BeginYear + "-" + input.BeginMonth + "-" + input.BeginDay);
			DateTime end = DateTime.Parse(input.EndYear + "-" + input.EndMonth + "-" + input.EndDay);
			list = await (from u in _meterRep.Context.Queryable<ElectricMeterFreeze>()
				where u.ElectricMeterFreezeTime >= begin && u.ElectricMeterFreezeTime <= end && snarr.Contains(u.Sn)
				select u).ToListAsync();
			format = "yyyy-MM-dd";
		}
		foreach (ExportMeterEnergyDto item in meterList)
		{
			item.date = DateTime.Parse(item.date).ToString(format);
			if (input.Type == 2)
			{
				item.FreezeCombinedActiveTotalElectricEnergy = list.Where((ElectricMeterFreeze u) => u.Sn == item.sn && u.ElectricMeterFreezeTime.ToString(format) == item.date).FirstOrDefault()?.CombinedActiveTotalElectricEnergy;
				item.FreezeCombinedActiveFlatElectricEnergy = list.Where((ElectricMeterFreeze u) => u.Sn == item.sn && u.ElectricMeterFreezeTime.ToString(format) == item.date).FirstOrDefault()?.CombinedActiveFlatElectricEnergy;
				item.FreezeCombinedActivePeakElectricEnergy = list.Where((ElectricMeterFreeze u) => u.Sn == item.sn && u.ElectricMeterFreezeTime.ToString(format) == item.date).FirstOrDefault()?.CombinedActivePeakElectricEnergy;
				item.FreezeCombinedActiveSharpElectricEnergy = list.Where((ElectricMeterFreeze u) => u.Sn == item.sn && u.ElectricMeterFreezeTime.ToString(format) == item.date).FirstOrDefault()?.CombinedActiveSharpElectricEnergy;
				item.FreezeCombinedActiveValleyElectricEnergy = list.Where((ElectricMeterFreeze u) => u.Sn == item.sn && u.ElectricMeterFreezeTime.ToString(format) == item.date).FirstOrDefault()?.CombinedActiveValleyElectricEnergy;
				item.FreezeCombinedActiveDeepValleyElectricEnergy = list.Where((ElectricMeterFreeze u) => u.Sn == item.sn && u.ElectricMeterFreezeTime.ToString(format) == item.date).FirstOrDefault()?.CombinedActiveDeepValleyElectricEnergy;
			}
		}
		IExcelExporter excelExporter = new ExcelExporter();
		return new FileStreamResult(new MemoryStream(await excelExporter.ExportAsByteArray(meterList)), "application/octet-stream")
		{
			FileDownloadName = DateTime.Now.ToString("yyyyMMddHHmm") + "用电量统计.xlsx"
		};
	}

	/// <summary>
	/// 导出水表用电量
	/// </summary>
	/// <returns></returns>
	[HttpPost("/energy/exportmeterwater")]
	[NonUnify]
	public async Task<IActionResult> ExporMeterWater([FromBody] EnergyInput input)
	{
		ISugarQueryable<ExportMeterWaterEnergyDto> data = GetWaterMeterQueryable(input);
		List<ExportMeterWaterEnergyDto> meterList = await data.OrderBy((ExportMeterWaterEnergyDto u) => u.sn).ToListAsync();
		string format = "yyyy";
		if (input.Type == 0)
		{
		}
		if (input.Type == 1)
		{
			format = "yyyy-MM";
		}
		if (input.Type == 2)
		{
			format = "yyyy-MM-dd";
		}
		foreach (ExportMeterWaterEnergyDto item in meterList)
		{
			item.date = DateTime.Parse(item.date).ToString(format);
		}
		IExcelExporter excelExporter = new ExcelExporter();
		return new FileStreamResult(new MemoryStream(await excelExporter.ExportAsByteArray(meterList)), "application/octet-stream")
		{
			FileDownloadName = DateTime.Now.ToString("yyyyMMddHHmm") + "用水量统计.xlsx"
		};
	}

	/// <summary>
	/// 导出抄表结算明细
	/// </summary>
	/// <returns></returns>
	[HttpPost("/energy/exportrecord")]
	[NonUnify]
	public async Task<IActionResult> ExportRecord([FromBody] EnergyInput input)
	{
		(ISugarQueryable<PowerConsumptionRecord>, DateTime, DateTime) input2 = GetInput(input);
		var (data, _, _) = input2;
		_ = input2.Item2;
		_ = input2.Item3;
		List<ExportConsumptionRecordDto> meterList = await data.OrderBy((PowerConsumptionRecord u) => u.CreateTime).Select<ExportConsumptionRecordDto>().ToListAsync();
		IExcelExporter excelExporter = new ExcelExporter();
		return new FileStreamResult(new MemoryStream(await excelExporter.ExportAsByteArray(meterList)), "application/octet-stream")
		{
			FileDownloadName = DateTime.Now.ToString("yyyyMMddHHmm") + "抄表结算明细.xlsx"
		};
	}

	/// <summary>
	/// 导出抄表结算明细
	/// </summary>
	/// <returns></returns>
	[HttpPost("/energy/exportrecordWater")]
	[NonUnify]
	public async Task<IActionResult> ExportRecordWater([FromBody] EnergyInput input)
	{
		(ISugarQueryable<WaterConsumptionRecord>, DateTime, DateTime) water2Input = GetWater2Input(input);
		var (data, _, _) = water2Input;
		_ = water2Input.Item2;
		_ = water2Input.Item3;
		List<ExportConsumptionWaterRecordDto> meterList = await data.OrderBy((WaterConsumptionRecord u) => u.CreateTime).Select<ExportConsumptionWaterRecordDto>().ToListAsync();
		IExcelExporter excelExporter = new ExcelExporter();
		return new FileStreamResult(new MemoryStream(await excelExporter.ExportAsByteArray(meterList)), "application/octet-stream")
		{
			FileDownloadName = DateTime.Now.ToString("yyyyMMddHHmm") + "抄表结算明细.xlsx"
		};
	}

	/// <summary>
	/// 获取综合报表
	/// </summary>
	/// <param name="input"></param>
	/// <returns></returns>
	[HttpPost("/energy/getcomprehensivestatement")]
	public async Task<StatementOutput> GetComprehensiveStatement([FromBody] StatementInput input)
	{
		new List<StatementCount>();
		List<MeterInfo> meterAllInfo = await (from u in _meterRep.Context.Queryable<ElectricMeter>()
			where input.Ids.Contains(u.Id) && u.IsDelete == false
			select new MeterInfo
			{
				MeterNo = u.Sn,
				Id = u.Id,
				Name = u.Name
			}).ToListAsync();
		StatementOutput output = new StatementOutput();
		DateTime startTime = input.Time.ToString("yyyy-01-01").ToDateTime();
		DateTime endTime = startTime.AddYears(1);
		string groupDateType = "month";
		output.Columns = new List<StatementColumns>
		{
			new StatementColumns
			{
				Key = "sn",
				Name = "表编号",
				Fixed = "left",
				Width = "140"
			},
			new StatementColumns
			{
				Key = "name",
				Name = "名称",
				Fixed = "left",
				Width = "140"
			}
		};
		if (input.Type == 0)
		{
			for (int i = 1; i < 13; i++)
			{
				output.Columns.Add(new StatementColumns
				{
					Key = "data" + i,
					Name = i + "月"
				});
			}
		}
		else if (input.Type == 1)
		{
			startTime = input.Time.ToString("yyyy-MM-01").ToDateTime();
			endTime = startTime.AddMonths(1);
			groupDateType = "day";
			DateTime i = startTime;
			while (i < endTime)
			{
				int day = i.Day;
				output.Columns.Add(new StatementColumns
				{
					Key = "data" + day,
					Name = day + "日"
				});
				i = i.AddDays(1.0);
			}
		}
		else if (input.Type == 2)
		{
			startTime = input.Time.ToString("yyyy-MM-dd HH:00:00").ToDateTime();
			endTime = startTime.AddDays(1.0);
			groupDateType = "hour";
			for (int i = 0; i < 24; i++)
			{
				output.Columns.Add(new StatementColumns
				{
					Key = "data" + i,
					Name = i + "时"
				});
			}
		}
		output.Columns.Add(new StatementColumns
		{
			Fixed = "right",
			Key = "total",
			Name = "合计",
			Width = "140"
		});
		List<StatementCount> result = await (from u in _rep.Context.Queryable<PowerConsumptionRecord>()
			where input.Ids.Contains(u.MeterId) && u.CreateTime >= startTime && u.CreateTime < endTime
			group u by SqlFunc.MappingColumn<string>($"meter_id,date_trunc('{groupDateType}', create_time)") into u
			select new StatementCount
			{
				MeterId = u.MeterId,
				Total = SqlFunc.AggregateSum(u.CombinedActiveTotalElectricEnergyDifference),
				Date = SqlFunc.MappingColumn<string>($"date_trunc('{groupDateType}', create_time)")
			}).ToListAsync();
		result.Select((StatementCount s) => s.MeterId).Distinct().ToList();
		output.TableDatas = new List<Dictionary<string, string>>();
		foreach (MeterInfo item in meterAllInfo)
		{
			Dictionary<string, string> dic = new Dictionary<string, string>();
			MeterInfo meter = item;
			dic.Add("sn", meter?.MeterNo ?? "--");
			dic.Add("name", meter?.Name ?? "--");
			List<StatementCount> tmpResult = result.Where((StatementCount w) => w.MeterId == item.Id).ToList();
			foreach (StatementCount item2 in tmpResult)
			{
				string key = ":";
				if (input.Type == 0)
				{
					key = "data" + item2.Date.ToDateTime().Month;
				}
				else if (input.Type == 1)
				{
					key = "data" + item2.Date.ToDateTime().Day;
				}
				else if (input.Type == 2)
				{
					key = "data" + item2.Date.ToDateTime().Hour;
				}
				dic.Add(key, Math.Round(item2.Total, 2).ToString());
			}
			decimal total = tmpResult.Select((StatementCount s) => s.Total).Sum();
			dic.Add("total", Math.Round(total, 2).ToString());
			output.TableDatas.Add(dic);
		}
		return output;
	}

	/// <summary>
	/// 获取分项能耗报表
	/// </summary>
	/// <param name="input"></param>
	/// <returns></returns>
	[HttpPost("/energy/getitemizestatement")]
	public async Task<StatementOutput> GetItemizeStatement([FromBody] StatementInput input)
	{
		new List<StatementCount>();
		var meterAllInfo = await (from u in _meterRep.Context.Queryable<LabelManagement>()
			where input.Ids.Contains(u.Id) && u.IsDelete == false
			select new { u.Id, u.Name }).ToListAsync();
		StatementOutput output = new StatementOutput();
		DateTime startTime = input.Time.ToString("yyyy-01-01").ToDateTime();
		DateTime endTime = startTime.AddYears(1);
		string groupDateType = "month";
		output.Columns = new List<StatementColumns>
		{
			new StatementColumns
			{
				Key = "name",
				Name = "分项",
				Fixed = "left",
				Width = "140"
			}
		};
		if (input.Type == 0)
		{
			for (int i = 1; i < 13; i++)
			{
				output.Columns.Add(new StatementColumns
				{
					Key = "data" + i,
					Name = i + "月"
				});
			}
		}
		else if (input.Type == 1)
		{
			startTime = input.Time.ToString("yyyy-MM-01").ToDateTime();
			endTime = startTime.AddMonths(1);
			groupDateType = "day";
			DateTime i = startTime;
			while (i < endTime)
			{
				int day = i.Day;
				output.Columns.Add(new StatementColumns
				{
					Key = "data" + day,
					Name = day + "日"
				});
				i = i.AddDays(1.0);
			}
		}
		else if (input.Type == 2)
		{
			startTime = input.Time.ToString("yyyy-MM-dd HH:00:00").ToDateTime();
			endTime = startTime.AddDays(1.0);
			groupDateType = "hour";
			for (int i = 0; i < 24; i++)
			{
				output.Columns.Add(new StatementColumns
				{
					Key = "data" + i,
					Name = i + "时"
				});
			}
		}
		output.Columns.Add(new StatementColumns
		{
			Fixed = "right",
			Key = "total",
			Name = "合计",
			Width = "140"
		});
		var meters = await (from u in _meterRep.Context.Queryable<ElectricMeter>()
			where u.LabelId != null && input.Ids.Contains((long)u.LabelId)
			select new { u.Id, u.LabelId }).ToListAsync();
		List<long> meterIds = meters.Select(s => s.Id).ToList();
		List<StatementCount> result = await (from u in _rep.Context.Queryable<PowerConsumptionRecord>()
			where meterIds.Contains(u.MeterId) && u.CreateTime >= startTime && u.CreateTime < endTime
			group u by SqlFunc.MappingColumn<string>($"meter_id,date_trunc('{groupDateType}', create_time)") into u
			select new StatementCount
			{
				MeterId = u.MeterId,
				Total = SqlFunc.AggregateSum(u.CombinedActiveTotalElectricEnergyDifference),
				Date = SqlFunc.MappingColumn<string>($"date_trunc('{groupDateType}', create_time)")
			}).ToListAsync();
		output.TableDatas = new List<Dictionary<string, string>>();
		foreach (var item in meterAllInfo)
		{
			Dictionary<string, string> dic = new Dictionary<string, string> { 
			{
				"name",
				item?.Name ?? "--"
			} };
			List<long> tmpMeterIds = (from w in meters
				where w.LabelId == item.Id
				select w into s
				select s.Id).ToList();
			List<StatementCount> tmpResult = result.Where((StatementCount w) => tmpMeterIds.Contains(w.MeterId)).ToList();
			foreach (StatementCount item2 in tmpResult)
			{
				string key = ":";
				if (input.Type == 0)
				{
					key = "data" + item2.Date.ToDateTime().Month;
				}
				else if (input.Type == 1)
				{
					key = "data" + item2.Date.ToDateTime().Day;
				}
				else if (input.Type == 2)
				{
					key = "data" + item2.Date.ToDateTime().Hour;
				}
				decimal value = Math.Round(item2.Total, 2);
				if (dic.ContainsKey(key))
				{
					if (decimal.TryParse(dic[key], out var tmpvalue))
					{
						dic[key] = Math.Round(tmpvalue + item2.Total, 2).ToString();
					}
				}
				else
				{
					dic.Add(key, value.ToString());
				}
			}
			decimal total = tmpResult.Select((StatementCount s) => s.Total).Sum();
			dic.Add("total", Math.Round(total, 2).ToString());
			output.TableDatas.Add(dic);
		}
		if (meterAllInfo.Count > 0)
		{
			Dictionary<string, string> totalDic = new Dictionary<string, string> { { "name", "合计" } };
			for (int i = 1; i < output.Columns.Count; i++)
			{
				string key = output.Columns[i].Key;
				totalDic.Add(value: Math.Round((from w in output.TableDatas
					where w.ContainsKey(key)
					select w into s
					select decimal.Parse(s[key])).Sum(), 2).ToString(), key: key);
			}
			output.TableDatas.Add(totalDic);
		}
		return output;
	}
}
